package org.dreamwork.tools.network.bridge.client.fx.controllers;

import com.google.gson.Gson;
import javafx.geometry.Dimension2D;
import netscape.javascript.JSObject;
import org.dreamwork.network.service.ServiceFactory;
import org.dreamwork.tools.network.bridge.client.data.Server;
import org.dreamwork.tools.network.bridge.client.services.IClientService;
import org.dreamwork.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by seth.yang on 2020/3/18
 */
public class ServerManagerWebPage extends AbstractWebPage {
    private final Logger logger = LoggerFactory.getLogger (ServerManagerWebPage.class);
    private final IClientService service = ServiceFactory.get (IClientService.class);

    ServerManagerWebPage () {
        super ("web-ui/server-manage.html");
        setResizable (false);
        setOnCloseListener (()-> bridge.confirmPageClose (null));
    }

    @Override
    protected Object performAction (String action, Object params) {
        if (!StringUtil.isEmpty (action)) {
            switch (action) {
                case "save":
                    return save ((String) params);
                case "remove":
                    return delete ((String) params);

                case "force-close":
                    if (stage != null) {
                        stage.close ();
                    }
                    break;

                default:
                    return true;
            }
        }
        return null;
    }

    @Override
    protected void onPageLoaded (JSObject window) {
        List<Server> list = service.getServers ();
        if (list != null && !list.isEmpty ()) {
            Map<String, Object> map = new HashMap<> ();
            map.put ("servers", list);
            bridge.firePageLoaded (new Gson ().toJson (map));
        }
    }

    @Override
    public Dimension2D getSize () {
        return new Dimension2D (660, 360);
    }

    private boolean save (String params) {
        try {
            Server server = new Gson ().fromJson (params, Server.class);
            Server shadow = service.get (server.getName ());
            if (shadow == null) {
                service.save (server);
            } else {
                boolean dirty = false;
                if (!shadow.getHost ().equals (server.getHost ())) {
                    shadow.setHost (server.getHost ());
                    dirty = true;
                }
                if (shadow.getConnectorPort ().intValue () != server.getConnectorPort ().intValue ()) {
                    shadow.setConnectorPort (server.getConnectorPort ());
                    dirty = true;
                }
                if (shadow.getManagePort ().intValue () != server.getManagePort ().intValue ()) {
                    shadow.setManagePort (server.getManagePort ());
                    dirty = true;
                }
                if (dirty) {
                    service.update (shadow);
                }
            }

            return true;
        } catch (Exception ex) {
            logger.warn (ex.getMessage (), ex);
            return false;
        }
    }

    private static final int EC_UNKNOWN       = -1;
    private static final int EC_OK            = 0x00;
    private static final int EC_SERVER_IN_USE = 0x01;

    private int delete (String name) {
        if (service.isServerInUse (name)) {
            return EC_SERVER_IN_USE;
        }

        int code = service.deleteServer (name);
        return code > 0 ? EC_OK : EC_UNKNOWN;
    }

/*
    public static final class WithToString {
        public String name = "this is a string";
        public int age = 55;
        public double weight = 58.32;
        public boolean married = true;
        public java.util.Date birthday = new java.util.Date ();

        public String getName () {
            return name;
        }

        public void setName (String name) {
            this.name = name;
        }

        public int getAge () {
            return age;
        }

        public void setAge (int age) {
            this.age = age;
        }

        public double getWeight () {
            return weight;
        }

        public void setWeight (double weight) {
            this.weight = weight;
        }

        public boolean isMarried () {
            return married;
        }

        public void setMarried (boolean married) {
            this.married = married;
        }

        @Override
        public String toString () {
            return "WithToString";
        }
    }

    public static final class WithoutToString {}
*/
}
